#include "stdafx.h"
#include "string_helper.h"
#include <algorithm>

namespace
{
	int my_isspace( int ch )
	{
		return (unsigned int)(ch - 9) < 5u  ||  ch == ' ';
	}
}

namespace base
{
namespace str
{
	std::string& replace(std::string& strBig, const std::string & strsrc, const std::string &strdst)
	{
		std::string::size_type pos = 0;
		while( (pos = strBig.find(strsrc, pos)) != std::string::npos)
		{
			strBig.replace(pos, strsrc.length(), strdst);
			pos += strdst.length();
		}
		return strBig;
	}

	std::wstring& replace(std::wstring& strBig, const std::wstring & strsrc, const std::wstring &strdst)
	{
		std::wstring::size_type pos = 0;
		while( (pos = strBig.find(strsrc, pos)) != std::wstring::npos)
		{
			strBig.replace(pos, strsrc.length(), strdst);
			pos += strdst.length();
		}
		return strBig;
	}

	std::string& makelower(std::string& strPram)
	{
		transform(strPram.begin(), strPram.end(), strPram.begin(), ::tolower);
		return strPram;
	}

	std::wstring& makelower(std::wstring& strPram)
	{
		transform(strPram.begin(), strPram.end(), strPram.begin(), ::towlower);
		return strPram;
	}

	std::string& makeupper(std::string& strPram)
	{
		transform(strPram.begin(), strPram.end(), strPram.begin(), ::toupper);
		return strPram;
	}

	std::wstring& makeupper(std::wstring& strPram)
	{
		transform(strPram.begin(), strPram.end(), strPram.begin(), ::towupper);
		return strPram;
	}

	std::string format(const char *strFormat, ...)
	{
		std::string strRet;
		va_list vlArgs = NULL;
		va_start(vlArgs, strFormat);
		size_t nLen = _vscprintf(strFormat, vlArgs) + 1;
		char *strBuffer = new char[nLen];
		_vsnprintf_s(strBuffer, nLen, nLen, strFormat, vlArgs);
		va_end(vlArgs);
		strRet = strBuffer;
		delete [] strBuffer;
		return strRet;
	}

	std::wstring format(const wchar_t *strFormat, ...)
	{
		std::wstring strRet;
		va_list vlArgs = NULL;
		va_start(vlArgs, strFormat);
		size_t nLen = _vscwprintf(strFormat, vlArgs) + 1;
		wchar_t *strBuffer = new wchar_t[nLen];
		_vsnwprintf_s(strBuffer, nLen, nLen, strFormat, vlArgs);
		va_end(vlArgs);
		strRet = strBuffer;
		delete [] strBuffer;
		return strRet;
	}
//split to vector----------------------------------
	int split(const std::string &s, const char *delim,std::vector<std::string> &ret)
	{
		ret.clear();
		size_t last = 0;
		size_t index=s.find_first_of(delim,last);
		while (index!=std::string::npos)
		{
			ret.push_back(s.substr(last,index-last));
			last=index+1;
			index=s.find_first_of(delim,last);
		}
		if (index-last>0 && !s.empty())
		{
			ret.push_back(s.substr(last,index-last));
		}
		return ret.size();
	}

	int split(const std::wstring &s, const wchar_t *delim,std::vector<std::wstring> &ret)
	{
		ret.clear();
		size_t last = 0;
		size_t index=s.find_first_of(delim,last);
		while (index != std::wstring::npos)
		{
			ret.push_back(s.substr(last,index-last));
			last=index+1;
			index=s.find_first_of(delim,last);
		}
		if (index-last>0 && !s.empty())
		{
			ret.push_back(s.substr(last,index-last));
		}
		return ret.size();
	}
//split to set---------------------------------------
	int split(const std::string &s, const char *delim,std::set<std::string> &ret)
	{
		ret.clear();
		size_t last = 0;
		size_t index=s.find_first_of(delim,last);
		while (index!=std::string::npos)
		{
			ret.insert(s.substr(last,index-last));
			last=index+1;
			index=s.find_first_of(delim,last);
		}
		if (index-last>0 && !s.empty())
		{
			ret.insert(s.substr(last,index-last));
		}
		return ret.size();
	}

	int split(const std::wstring &s, const wchar_t *delim,std::set<std::wstring> &ret)
	{
		ret.clear();
		size_t last = 0;
		size_t index=s.find_first_of(delim,last);
		while (index != std::wstring::npos)
		{
			ret.insert(s.substr(last,index-last));
			last=index+1;
			index=s.find_first_of(delim,last);
		}
		if (index-last>0 && !s.empty())
		{
			ret.insert(s.substr(last,index-last));
		}
		return ret.size();
	}

	std::string& trimLeft( std::string &ss )
	{
		std::string::iterator it    = ss.begin();
		std::string::iterator end    = ss.end();

		while (it != end && my_isspace(*it)) ++it;
		ss.erase(ss.begin(), it);
		return ss;
	}

	std::string& trimRight( std::string &ss )
	{
		int pos = int(ss.size()) - 1;

		while (pos >= 0 && my_isspace(ss[pos])) --pos;
		ss.resize(pos + 1);

		return ss;
	}

	std::string& trim( std::string &st )
	{
		return trimLeft(trimRight(st));
	}

	std::wstring& trimLeft( std::wstring &ss )
	{
		std::wstring::iterator it    = ss.begin();
		std::wstring::iterator end    = ss.end();
		while (it != end && my_isspace(*it)) ++it;
		ss.erase(ss.begin(), it);
		return ss;
	}

	std::wstring& trimRight( std::wstring &ss )
	{
		int pos = int(ss.size()) - 1;
		while (pos >= 0 && my_isspace(ss[pos])) --pos;
		ss.resize(pos + 1);
		return ss;
	}

	std::wstring& trim( std::wstring &st )
	{
		return trimLeft(trimRight(st));
	}

	bool isChineseChar(const wchar_t wch)
	{
		if ((wch >= 0) && (wch <= 0x7F))
		{
			return false;
		}
		return true;
	}
}
}

